package com.oig.sys.workflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.oig.common.exception.BadRequestException;
import com.oig.sys.workflow.constants.FlowEnums;
import com.oig.sys.workflow.dao.ITbFlowFormDao;
import com.oig.sys.workflow.dto.FlowFormDto;
import com.oig.sys.workflow.entity.TbFlowConfig;
import com.oig.sys.workflow.entity.TbFlowForm;
import com.oig.sys.workflow.service.ITbFlowFormService;
import com.oig.sys.workflow.vo.FlowFormVo;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wuxl
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TbFlowFormServiceImpl implements ITbFlowFormService {

	private final ITbFlowFormDao tbFlowFormDao;


	private FlowFormVo addFlowForm(FlowFormDto flowFormDto){
		TbFlowForm flowForm = tbFlowFormDao.getByFlowConfigIdAndFieldId(flowFormDto.getFlowConfigId(), flowFormDto.getFieldId()) ;
		if (flowForm!=null){
			throw new BadRequestException("field重复") ;
		}
		flowForm = BeanUtil.copyProperties(flowFormDto, TbFlowForm.class, "id");
		this.tbFlowFormDao.save(flowForm);
		return BeanUtil.copyProperties(flowForm, FlowFormVo.class);
	}

	private FlowFormVo updateFlowForm(FlowFormDto flowFormDto){
		TbFlowForm flowForm = tbFlowFormDao.getTbFlowFormById(flowFormDto.getId());
		if (flowForm==null){
			throw new BadRequestException("记录不存在") ;
		}
		if (!flowForm.getFlowConfigId().equals(flowFormDto.getFlowConfigId())){
			throw new BadRequestException("明细id传错");
		}
		if (!flowForm.getFieldId().equals(flowFormDto.getFieldId())){
			TbFlowForm od = this.tbFlowFormDao.getByFlowConfigIdAndFieldId(flowForm.getFlowConfigId(), flowForm.getFieldId());
			if (od!=null){
				throw new BadRequestException("field重复") ;
			}
		}
		BeanUtil.copyProperties(flowFormDto, flowForm);
		this.tbFlowFormDao.save(flowForm);
		return BeanUtil.copyProperties(flowForm, FlowFormVo.class);
	}


	@Transactional
	@Override
	public List<FlowFormVo> addFlowFormList(TbFlowConfig flowConfig, FlowFormVo parent, List<FlowFormDto> flowFormDtoList) {
		List<FlowFormVo> detailVoList = new ArrayList<>();
		for (FlowFormDto flowFormDto : flowFormDtoList){
			flowFormDto.setFlowConfigId(flowConfig.getId());
			if (parent!=null){
				flowFormDto.setParentId(parent.getId());
			} else {
				flowFormDto.setParentId(0);
			}
			FlowFormVo formVo = this.addFlowForm(flowFormDto);
			detailVoList.add(formVo);
			if (FlowEnums.FormType.FIELD_LIST.getCode().equals(flowFormDto.getFieldType())){
				if (CollectionUtil.isEmpty(flowFormDto.getChildren())){
					throw new BadRequestException(flowFormDto.getFieldName()+"子表单不能为空") ;
				}
				formVo.setChildren(this.addFlowFormList(flowConfig, formVo, flowFormDto.getChildren()));
			}
		}
		return detailVoList;
	}

	@Transactional
	@Override
	public List<FlowFormVo> updateFlowFormList(TbFlowConfig flowConfig, FlowFormVo parent, List<FlowFormDto> flowFormDtoList) {
		List<FlowFormVo> detailVoList = new ArrayList<>();
		List<Integer> idList = new ArrayList<>();
		for (FlowFormDto flowFormDto : flowFormDtoList){
			flowFormDto.setFlowConfigId(flowConfig.getId());
			if (parent!=null){
				flowFormDto.setParentId(parent.getId());
			} else {
				flowFormDto.setParentId(0);
			}
			FlowFormVo flowFormVo ;
			if (flowFormDto.getId()!=null){
				flowFormVo = this.updateFlowForm(flowFormDto);
			} else {
				flowFormVo = this.addFlowForm(flowFormDto);
			}
			idList.add(flowFormVo.getId());
			detailVoList.add(flowFormVo);
			if (FlowEnums.FormType.FIELD_LIST.getCode().equals(flowFormDto.getFieldType())){
				if (CollectionUtil.isEmpty(flowFormDto.getChildren())){
					throw new BadRequestException(flowFormDto.getFieldName()+"子表单不能为空") ;
				}
				flowFormVo.setChildren(this.updateFlowFormList(flowConfig, flowFormVo, flowFormDto.getChildren()));
			}
		}
		int pid = 0;
		if (parent!=null){
			pid = parent.getId();
		}
		List<Integer> delIdList = this.tbFlowFormDao.findAllDelId(flowConfig.getId(), pid, idList) ;
		if (CollectionUtil.isNotEmpty(delIdList)){
			this.delFlowForms(delIdList);
		}
		return detailVoList;
	}

	private void delFlowForms(List<Integer> delIdList){
		List<TbFlowForm> delFlowList = this.tbFlowFormDao.findByIdList(delIdList);
		for (TbFlowForm flowForm : delFlowList){
			if (FlowEnums.FormType.FIELD_LIST.getCode().equals(flowForm.getFieldType())){
				List<TbFlowForm> children = this.tbFlowFormDao.findByFlowConfigIdAndParentId(flowForm.getFlowConfigId(), flowForm.getId());
				this.tbFlowFormDao.deleteAll(children);
			}
		}
		this.tbFlowFormDao.deleteAll(delFlowList);
	}

	@Override
	public List<FlowFormVo> findFlowFormByCfgId(Integer configId, Integer parentId) {
		List<TbFlowForm> flowFormList = tbFlowFormDao.findByFlowConfigIdAndParentId(configId,parentId);
		List<FlowFormVo> voList = new ArrayList<>();
		flowFormList.forEach(item->{
			FlowFormVo formVo = BeanUtil.copyProperties(item,FlowFormVo.class);
			if (FlowEnums.FormType.FIELD_LIST.getCode().equals(item.getFieldType())){
				formVo.setChildren(this.findFlowFormByCfgId(configId, formVo.getId()));
			}
			voList.add(formVo);
		});
		return voList;
	}
}
